WebView2 使用及现状

您所在的位置:网站首页 webview2 vue exe WebView2 使用及现状

WebView2 使用及现状

2024-03-05 18:15| 来源: 网络整理| 查看: 265

前言

之前写过一篇文章来介绍WebView2:.Net桌面端开发使用WebView2,可以放弃CefSharp? 当时WebView2还是预览版,截止到今天,官方已经更新到1.0.705.50正式版本,对应的chrome 内核版本为:88.0.705.74,可以说更新的还挺频繁。刚好公司有个项目使用了CefSharp,就深入研究了一下WebView2的使用,这篇文章就来详细记录一下我的使用体验吧。

最新实战记录了WebView2的注意事项:WebView2的注意事项

老规矩,写技术类文章不注明开发环境还不如不写。

环境

运行环境:.Net Framework 4.5.2 (由于我的项目是基于452,所以这里没有用.Net 5) 开发环境:VS2019 16.8.2 框架语言:WPF

安装及使用

这个安装过程在上篇文章已经有了,就不再详述。 由于WebView2是基于Chrome内核的,所以必须有Chrome内核环境,有如下三种方式可以获取:

安装开发版的Edge (Chromium),稳定版的Edge目前不支持WebView2控件。安装独立的WebView2 Runtime,它可以独立下载和升级 嵌入Edge chromium内核嵌入Edge chromium内核 以上三种方法都可通过这个官方链接下载 初始化

有两种方法使用WebView2,上篇文章没有详细写第二种,再把官方文档的说明贴一下: 必须对CoreWebView2进行初始化,看一下微软官方的解释是因为创建 CoreWebView2 是一个昂贵的操作,它涉及启动 Edge 浏览器进程之类的操作。 有两种方法可导致创建 CoreWebView2: 1)设置 Source 属性(例如,可以通过标记执行此操作)。 这称为隐式初始化。 2)调用 EnsureCoreWebView2Async 方法。 这称为显式初始化。

在使用第二种方法的时候需要特别注意:

if (this.webView != null) { var path = AppDomain.CurrentDomain.BaseDirectory + "WebViewCache"; var env = await CoreWebView2Environment.CreateAsync(userDataFolder: path); await webView.EnsureCoreWebView2Async(); webView.CoreWebView2.Navigate("www.bing.com"); }

如果只是在初始化的时候这么写,会发现最后一句话会报错,提示webView.CoreWebView2为空异常,这是因为创建 CoreWebView2 是通过调用底层的Chrome内核来初始化的,这里的await并不是等待CoreWebView2创建成功返回,而是等待去创建这个操作成功了返回。而真正的CoreWebView2的初始化才刚开始,所以下面直接执行Navigate报空异常。这里先需要注册一个CoreWebView2InitializationCompleted回调来等待CoreWebView2的初始化完成,

private void WebView_CoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e) { if (webView.CoreWebView2 != null) { webView.CoreWebView2.Navigate("www.bing.com"); } }

这样就可以了。

另外,在初始化的时候可以进行初始化环境配置 userDataFolder:设置用户目录 browserExecutableFolder:设置Chrome内核路径 options:环境相关参数

if (this.webView != null) { var path = AppDomain.CurrentDomain.BaseDirectory + "WebViewCache"; var env = await CoreWebView2Environment.CreateAsync(userDataFolder: path,browserExecutableFolder:path,options:new CoreWebView2EnvironmentOptions()); await webView.EnsureCoreWebView2Async(env);

在我使用的当前环境下测试发现browserExecutableFolder这个内嵌Chrome内核的方式直接报错,可能是bug,或者是我的使用方式问题(虽然我自认就是按官方教程正确设置的),如果有高手欢迎指正

同时在初始化完成后可以对WebView2进行一些基本的功能设置

if (webView.CoreWebView2 != null) { webView.CoreWebView2.Settings.AreDefaultContextMenusEnabled = false; webView.CoreWebView2.Settings.AreDevToolsEnabled = false; webView.CoreWebView2.Settings.IsZoomControlEnabled = false; webView.CoreWebView2.Settings.IsStatusBarEnabled = false; }

AreDefaultContextMenusEnabled :禁用网页右键功能 AreDevToolsEnabled:禁用开发工具,设为true,可通过F12打开开发者调试功能 IsZoomControlEnabled:禁用网页的放大缩小功能 IsStatusBarEnabled:禁用网页上加载页面的进度条功能

注册事件 webView.CoreWebView2.NavigationStarting += WebView_NavigationStarting; webView.CoreWebView2.NavigationCompleted += WebView_NavigationCompleted; webView.CoreWebView2.WebMessageReceived += CoreWebView2_WebMessageReceived; webView.CoreWebView2.NewWindowRequested += CoreWebView2_NewWindowRequested; ...

WebView_NavigationStarting:跳转开始回调 WebView_NavigationCompleted:跳转结束回调 CoreWebView2_WebMessageReceived:收到页面消息回调 CoreWebView2_NewWindowRequested:打开新窗口时回调 下面演示在跳转开始判断当前地址是否是https,如果不是则取消跳转。

private void WebView_NavigationStarting(object sender, CoreWebView2NavigationStartingEventArgs e) { String uri = e.Uri; this.txtUrl.Text = uri; if (!uri.StartsWith("https://")) { //Uri webView.CoreWebView2.ExecuteScriptAsync($"alert('{uri} is not safe, try an https link')"); e.Cancel = true; } }

以上只列出了几个常用的事件,详细可以查看官方文档:CoreWebView

与网页通信

客户端调用网页JS方法

if (webView.CoreWebView2 != null) { webView.CoreWebView2.ExecuteScriptAsync($"test('{this.txtUrl.Text}')"); }

JS调用客户端方法 这里略复杂一点,需要先注册一下AddHostObjectToScript:

webView.CoreWebView2.AddHostObjectToScript("bridge", new JavaScriptBridge());

在写一个类,专门用来提供给JS调用:JavaScriptBridge 这里需要注意必须得加上[ComVisible(true)]属性

[ComVisible(true)] public class JavaScriptBridge { public string Func(string param) { string tmp = param; return tmp + "测试一下呀"; } }

在网页端:

const bridge = chrome.webview.hostObjects.bridge; console.log(await bridge.Func("testing...")); 部署应用

根据开头初始化提到的三种依赖方式,在实际使用中,可能第三种方式比较适合,即通过安装独立的WebView2 Runtime,也就是官方说的常青版程序,这个是将Chrome内核打包成一个程序,安装好就能受到官方的升级更新服务。 在这里插入图片描述 在运行程序前先检测一下是否安装了正确的内核程序: 由于安装程序过程并不可控,我这里用了比较笨的方法,就是在程序执行前每隔三秒去检测环境是否安装好。

[STAThread] public static void Main() { if (!CheckWebView()) { MessageBox.Show("检测到当前未安装运行环境,正在启动安装程序,请稍后..."); InstallWebView(); Stopwatch.StartNew(); while (!CheckWebView()) { Thread.Sleep(3000); } } var application = new App(); application.InitializeComponent(); application.Run(); } private static bool CheckWebView() { try { var str = CoreWebView2Environment.GetAvailableBrowserVersionString(); if (!string.IsNullOrWhiteSpace(str)) { return true; } } catch (Exception) { return false; } return false; } private static void InstallWebView() { var path = AppDomain.CurrentDomain.BaseDirectory + "check"; using (Process process = new Process()) { process.StartInfo.UseShellExecute = false; process.StartInfo.FileName = path + "\\MicrosoftEdgeWebview2Setup.exe"; try { process.Start(); } catch (Exception ex) { //MessageBox.Show(ex.Message); } } }

通过这个方法,就可以把Cefsharp那一堆内核程序从安装包里删除,大大缩小了软件包

现状

一切都看起来很美好,然而… 我在实际使用过程中,发现WebView2目前对WPF并不友好,直接上图: 在这里插入图片描述 发现了吗?所有写在WebView2后面的代码全被覆盖了,我一开始以为是我的使用问题,经过在github上官方反馈,才得知这是一个已知的bug,而且提了有一年多了,并没有解决这个问题,Issue,甚至有外国程序员发贴diss 在这里插入图片描述 这个问题目前官方并没有明确的修复日期,希望官方能早日解决吧。

更新于2022年1月25日,这个问题官方在最新预览版本已解决,详细请查看WebView2 终于修复了页面 UI 可见性没有随 WebView2 可见性而更改的 Bug



【本文地址】


今日新闻


推荐新闻


    CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3